home *** CD-ROM | disk | FTP | other *** search
- /*
- **
- ** $Id: process.c,v 1.2 1995/10/07 02:52:52 chris Exp $
- ** $Revision: 1.2 $
- **
- ** $Filename: developer/process.c $
- ** $Author: chris $
- ** $Date: 1995/10/07 02:52:52 $
- ** $Portability: AMIGADOS $
- **
- ** Prozess-Verwaltung
- **
- ** THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF RELOG AG.
- **
- ** COPYRIGHT (C) 1991-1996 BY RELOG AG, ZUERICH. ALL RIGHTS RESERVED.
- ** NO PART OF THIS SOFTWARE MAY BE COPIED, REPRODUCED, OR TRANSMITTED
- ** IN ANY FORM OR BY ANY MEANS, WITHOUT THE PRIOR WRITTEN PERMISSION
- ** OF RELOG AG.
- **
- */
-
- #include "OS.h"
-
- #define _PROCESS
- #include "process.h"
- #include "arexx.h"
-
- #include <proto/exec.h>
- #include <exec/memory.h>
- #include <proto/dos.h>
- #include <dos/dostags.h>
-
- #include <stdio.h>
- #include <string.h>
-
- #define STACKSIZE 8192 /* Stapelgrösse des Message-Handler-Prozesses */
-
-
- struct ProcEnv
- {
- struct Message Message; /* Wird dem Prozess geschickt */
-
- PROCFUNC Func; /* Handler-Funktion */
- VOID *Para; /* Parameter der Handler-Funktion */
-
- struct Process *Process; /* Zeiger auf Prozess oder NULL */
-
- struct ARexxPort *RexxPort; /* Zeiger auf REXX-Port */
- char PortName[32]; /* REXX-Port-Name */
- };
-
-
- struct MsgPort *proclistport; /* Liste aller ProcEnv-Strukturen */
-
-
- /****** Process_Create ******************************************************
- *
- * NAME
- * Process_Create -- Create a process
- *
- * SYNOPSIS
- * pid = Process_Create( func, userdata, name, priority );
- *
- * U32 Process_Create( BOOL (*)( U32 ), U32, U8 *, S8 );
- *
- * FUNCTION
- * This function creates a process which will basically sleep. Whenever
- * Process_Wakeup() with its pid is called, the process will wake up and
- * call `func' with `userdata' as its sole argument. When the function
- * returns, the process will fall asleep anew.
- * If func returns FALSE, the process will self-terminate.
- *
- * Additionally, an AREXX message port will be created, and AREXX
- * messages will be handled.
- *
- * INPUTS
- * func - Function to be called, or NULL if this is an AREXX
- * handler process.
- * userdata - Will be passed to func and all AREXX functions
- * name - Name of the process
- * priority - Process priority [-128..127]
- *
- * RESULT
- * pid - Process ID.
- *
- * SEE ALSO
- *
- ****************************************************************************/
-
- static VOID __saveds ProcessEntry( VOID )
- {
- struct Process *me = (struct Process *)FindTask( NULL );
- struct ProcEnv *env;
-
- /*
- ** Startup-Message mit Environment abholen
- */
- WaitPort( &me->pr_MsgPort );
- env = (struct ProcEnv *)GetMsg( &me->pr_MsgPort );
-
-
- /*
- ** ARexx-Port erzeugen, falls keine Handler-Funktion angegeben wurde
- */
- if (env->Func == NULL)
- {
- OS_sprintf( env->PortName, "AM-%08lx", env->Process );
- env->RexxPort = ARexx_CreatePort( env->PortName, env->Para ); /* $$$ Abfrage? */
- }
-
-
- /*
- ** Initialisierung ist jetzt beendet, Env wird zurückgeschickt.
- */
- ReplyMsg( &env->Message );
-
-
- /*
- ** Hauptschleife
- */
- for (;;)
- {
- U32 mask = SIGBREAKF_CTRL_C | SIGF_SINGLE;
-
- if (env->RexxPort != NULL)
- mask |= 1UL << env->RexxPort->Port->mp_SigBit;
-
- if (Wait( mask ) & SIGBREAKF_CTRL_C )
- break;
-
- if (env->Func != NULL)
- {
- if (!(*env->Func)( env->Para ))
- break;
- }
- else if (env->RexxPort != NULL)
- {
- ARexx_HandleMessages( env->RexxPort );
- }
- }
-
- if (env->RexxPort != NULL)
- {
- ARexx_DeletePort( env->RexxPort );
- env->RexxPort = NULL;
- }
-
- env->Process = NULL;
- }
-
-
- U32
- Process_Create( PROCFUNC func, VOID *para, U8 *name, S8 pri )
- {
- struct ProcEnv *env;
-
- if (proclistport == NULL)
- {
- printf( "Creating the first process, initializing proclistport\n" );
- if (!(proclistport = CreateMsgPort()))
- return NULL;
- }
-
- if ((env = OS_Malloc( sizeof( *env ) )) != NULL)
- {
- env->Func = func;
- env->Para = para;
-
- /*
- ** Message-Handler-Prozess erzeugen
- */
- if (env->Process = CreateNewProcTags(
- NP_Entry, (U32)ProcessEntry,
- NP_Name, (U32)name,
- NP_Priority, (S32)pri,
- NP_StackSize, STACKSIZE,
- NP_Output, Output(),
- NP_CloseOutput, FALSE,
- TAG_DONE
- ))
- {
- if (env->Message.mn_ReplyPort = CreateMsgPort())
- {
- /*
- ** Startup-Message zum neuen Prozess schicken und warten,
- ** bis sie wieder zurückgekommen ist
- */
- PutMsg( &env->Process->pr_MsgPort, &env->Message );
- WaitPort( env->Message.mn_ReplyPort );
- DeleteMsgPort( env->Message.mn_ReplyPort );
- env->Message.mn_ReplyPort = NULL;
-
- /* env in die Prozessliste eintragen */
- PutMsg( proclistport, &env->Message );
-
- printf( "Created process 0x%08lx\n", env );
- return (U32)env;
- }
-
- /* $$$ Oehm... da liegt jetzt so ein toter Prozess rum! */
- }
-
- OS_Free( env );
- }
-
- return (U32)NULL;
- }
-
-
- /****** Process_Delete ******************************************************
- *
- * NAME
- * Process_Delete -- Delete a process
- *
- * SYNOPSIS
- * Process_Delete( pid );
- *
- * VOID Process_Delete( U32 );
- *
- * FUNCTION
- * This function kills a process.
- *
- * INPUTS
- *
- * RESULT
- *
- * SEE ALSO
- *
- ****************************************************************************/
-
- VOID
- Process_Delete( U32 pid )
- {
- struct ProcEnv *env = (struct ProcEnv *)pid;
-
- Forbid();
- if (Process_IsValidPID( pid ))
- {
- U16 i;
-
- Remove( &env->Message.mn_Node );
-
- for (i=0; i < 20; ++i) /* 4 Sekunden */
- {
- if (env->Process != NULL)
- Signal( &env->Process->pr_Task, SIGBREAKF_CTRL_C );
-
- if (env->Process == NULL)
- break;
-
- OS_Delay( 100 );
- }
-
- printf( "Deleting process 0x%08lx\n", env );
- OS_Free( env );
- /* env = NULL; */
- }
-
- if (ISLISTEMPTY( (IC_LIST *)&proclistport->mp_MsgList ))
- {
- printf( "This was the last process, deleting proclistport\n" );
- DeleteMsgPort( proclistport );
- proclistport = NULL;
- }
- Permit();
- }
-
-
- /****** Process_WakeUp ******************************************************
- *
- * NAME
- * Process_WakeUp -- Signal a process to wake up
- *
- * SYNOPSIS
- * Process_WakeUp( pid );
- *
- * VOID Process_WakeUp( U32 );
- *
- * FUNCTION
- *
- * INPUTS
- *
- * RESULT
- *
- * SEE ALSO
- *
- ****************************************************************************/
-
- VOID
- Process_WakeUp( U32 pid )
- {
- struct ProcEnv *env = (struct ProcEnv *)pid;
-
- Forbid();
- if (Process_IsValidPID( pid ))
- {
- Signal( &env->Process->pr_Task, SIGF_SINGLE );
- }
- Permit();
- }
-
-
- /****** Process_IsValidPID ******************************************************
- *
- * NAME
- * Process_IsValidPID -- Test if a pid is valid
- *
- * SYNOPSIS
- * Process_IsValidPID( pid );
- *
- * VOID Process_IsValidPID( U32 );
- *
- * FUNCTION
- * Tests if there's a process running with pid.
- *
- * INPUTS
- *
- * RESULT
- * TRUE if valid, FALSE if not.
- *
- * SEE ALSO
- *
- ****************************************************************************/
-
- BOOL
- Process_IsValidPID( U32 pid )
- {
- struct ProcEnv *env = (struct ProcEnv *)pid, *e2;
-
- Forbid();
- if (proclistport != NULL)
- {
- DOLIST( (IC_LIST *)&proclistport->mp_MsgList, e2 )
- {
- if (e2 == env)
- {
- Permit();
- return TRUE;
- }
- }
- }
- Permit();
-
- printf( "WARNING: IsValidPID( 0x%08lx ) failed!\n", pid );
- return FALSE;
- }
-
-
- struct ARexxPort *
- Process_GetRexxPort( U32 pid )
- {
- struct ProcEnv *env = (struct ProcEnv *)pid;
-
- if (Process_IsValidPID( pid ))
- {
- return env->RexxPort;
- }
-
- return NULL;
- }
-
-